package com.smartcommunity.service.dataImport;

import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Sets;
import com.smartcommunity.base.bean.ExceptionCode;
import com.smartcommunity.base.common.CacheMap;
import com.smartcommunity.base.common.DataImport;
import com.smartcommunity.base.common.PicImport;
import com.smartcommunity.bean.constant.Constant;
import com.smartcommunity.bean.entity.ImportErrorMsg;
import com.smartcommunity.bean.entity.ImportField;
import com.smartcommunity.controller.DataImportBase;
import com.smartcommunity.dao.tag.TagDao;
import com.smartcommunity.dao.village.RealPowerOrgDao;
import com.smartcommunity.entity.people.RealPower;
import com.smartcommunity.entity.tag.ObjectTag;
import com.smartcommunity.entity.tag.Tag;
import com.smartcommunity.exception.BusinessException;
import com.smartcommunity.log.interceptor.Log;
import com.smartcommunity.service.dataImport.model.RealPowerExportModel;
import com.smartcommunity.utils.RegExUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

import static org.apache.commons.lang3.StringUtils.*;

@Component("realPower")
@Slf4j
public class RealPowerImport extends DataImportBase implements DataImport, PicImport {

    @Autowired
    private RealPowerOrgDao dao;

    @Autowired
    private TagDao tagDao;

    /**
     * 模板类型
     */
    private String type = "实有力量";

    /**
     * 内容标题
     */
    private  String[] headerTitle = new String[]{
            "证件类型",
            "证件号码",
            "姓名",
            "居住地址",
            "手机号码",
            "所属公司名称",
            "实有力量标签"};
    /**
     * 错误信息
     */
    private  String[] headerErrorMsg = new String[]{
            "为空",
            "为空、或格式错误",
            "为空、或长度超过100位",
            "长度超过64位",
            "不是数字、或长度超过20位",
            "长度超过64位",
            "为空、或所填写的标签在系统中不存在"};

    /**
     * key taskId,value progress
     */
    final int cacheSize = 100000;
    Map<String, Integer> progressTag = new LinkedHashMap<String, Integer>((int) Math.ceil(cacheSize / 0.75f) + 1, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<String, Integer> eldest) {
            return size() > cacheSize;
        }
    };

    Map<String, Integer> progressPicTag = new LinkedHashMap<String, Integer>((int) Math.ceil(cacheSize / 0.75f) + 1, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<String, Integer> eldest) {
            return size() > cacheSize;
        }
    };

    @Override
    @Log(info = "实有力量模板导入")
    public String importData (List list, String villageCode,String fileName, String taskId,HttpServletResponse response) throws IllegalArgumentException, BusinessException {
        progressTag.put(taskId, 10);
        //小区编号（必填）
        if (StringUtils.isBlank(villageCode)) {
            throw new IllegalArgumentException("小区编号为空！");
        }
        //初始化导入模板信息
        ImportErrorMsg msg = getFiledInfo(type,headerTitle,headerErrorMsg);
        //字段校验信息
        List<ImportField> fieldList = msg.getFieldList();

        //获取所有标签信息
        List<ObjectTag> tagList = new ArrayList<>();
        Map<String, Tag> tagMap = new HashMap<>();
        List<Tag> tags = tagDao.getTagList(null);
        for(Tag tag :tags){
            tagMap.put(tag.getTagName(),tag);
        }

        List<RealPower> powerList = new ArrayList<>();
        List<Object[]> objList = (List<Object[]>) list;
        //存储错误信息
        List<RealPowerExportModel> dataListCopy = new ArrayList<>();
        int size = objList.size();
        int errorCount = 0;

        for (int i = 0; i < size; i++) {
            boolean isError = false;

            int currentRow = Constant.START_ROW + i;
            Object[] objects = objList.get(i);

            int fixColumnLen = 7;
            if(objects.length < fixColumnLen){
                throw new BusinessException("模板文件列数不对，请检查模板文件！");
            }

            // 空行校验，跳过空行
            List<String> oneLine = Arrays.stream(objects)
                    .map(o -> StrUtil.trim(Objects.toString(o, EMPTY)))
                    .collect(Collectors.toList());
            if(oneLine.stream().allMatch(StrUtil::isEmpty)){
                log.info("第{}行全为空，跳过该行",currentRow);
                continue;
            }

            RealPower realPower = new RealPower();

            StringBuffer errorMessages = new StringBuffer();
            // 设置小区编码（必填）
            realPower.setVillageCode(villageCode);

            // 设置证件类型（必填）
            String credentialType = "null".equals(String.valueOf(objects[0])) ? "" : String.valueOf(objects[0]);
            if (StringUtils.isBlank(credentialType) || CacheMap.CREDENTIAL_TYPE_NAME_MAP.get(credentialType)==null) {
                //添加错误的行数
                String errorMsg = appendErrorMsg(fieldList.get(0).getTitle(), credentialType, fieldList.get(0).getErrorMsg());
                errorMessages.append(errorMsg);
                isError = true;
            }else{
                realPower.setCredentialType(String.valueOf(CacheMap.CREDENTIAL_TYPE_NAME_MAP.get(credentialType)));
            }

            // 设置证件号（必填）
            String credentialNo = "null".equals(String.valueOf(objects[1])) ? "" : String.valueOf(objects[1]);
            if (StringUtils.isBlank(credentialNo)) {
                String errorMsg = appendErrorMsg(fieldList.get(1).getTitle(), credentialNo, fieldList.get(1).getErrorMsg());
                errorMessages.append(errorMsg);
                isError = true;
            }else {
                if(length(credentialNo)>18){
                    String errorMsg = appendErrorMsg(fieldList.get(1).getTitle(), credentialNo, fieldList.get(1).getErrorMsg());
                    errorMessages.append(errorMsg);
                    isError = true;
                }
                //判断是否是居民身份证
                if (Constant.IDCARD_NAME_VALUE.equals(credentialType)) {
                    if (!RegExUtils.isIdCardNo(credentialNo)) {
                        String errorMsg = appendErrorMsg(fieldList.get(1).getTitle(), credentialNo, fieldList.get(1).getErrorMsg());
                        errorMessages.append(errorMsg);
                        isError = true;
                    }
                }
                realPower.setCredentialNo(credentialNo);
            }

            // 姓名(必填)
            String certificatesName = "null".equals(String.valueOf(objects[2])) ? "" : String.valueOf(objects[2]);
            if (StringUtils.isBlank(certificatesName) || length(certificatesName)>100) {
                String errorMsg = appendErrorMsg(fieldList.get(2).getTitle(), certificatesName, fieldList.get(2).getErrorMsg());
                errorMessages.append(errorMsg);
                isError = true;
            }else{
                realPower.setCertificatesName(certificatesName);
            }

            // 居住地址（选填)
            String residentialAddress = "null".equals(String.valueOf(objects[3])) ? "" : String.valueOf(objects[3]);
            if (!StringUtils.isBlank(residentialAddress)) {
                if(length(residentialAddress)>64){
                    String errorMsg = appendErrorMsg(fieldList.get(3).getTitle(), residentialAddress, fieldList.get(3).getErrorMsg());
                    errorMessages.append(errorMsg);
                    isError = true;
                }
                realPower.setResidentialAddress(residentialAddress);
            }

            // 手机号码（选填)
            String phoneNumber = "null".equals(String.valueOf(objects[4])) ? "" : String.valueOf(objects[4]);
            if (!StringUtils.isBlank(phoneNumber)) {
                if(length(phoneNumber)>20 || !RegExUtils.isNumeric(phoneNumber)){
                    String errorMsg = appendErrorMsg(fieldList.get(4).getTitle(), phoneNumber, fieldList.get(4).getErrorMsg());
                    errorMessages.append(errorMsg);
                    isError = true;
                }
                realPower.setPhoneNumber(phoneNumber);
            }

            // 所属公司（选填)
            String companyName = "null".equals(String.valueOf(objects[5])) ? "" : String.valueOf(objects[5]);
            if (!StringUtils.isBlank(companyName)) {
                if(length(companyName)>64){
                    String errorMsg = appendErrorMsg(fieldList.get(5).getTitle(), phoneNumber, fieldList.get(5).getErrorMsg());
                    errorMessages.append(errorMsg);
                    isError = true;
                }
                realPower.setCompanyName(companyName);
            }


            // 标签，中文，逗号分隔(必填)
            boolean hasTag = false;
            String tagInput = "null".equals(String.valueOf(objects[6])) ? "" : String.valueOf(objects[6]);
            if (isNotBlank(tagInput)) {
                Set<String> tagNames = Sets.newHashSet(SpTagName.splitToList(tagInput));
                for(String tagName :tagNames){
                    if(tagMap.containsKey(tagName)){
                        Integer tagId = tagMap.get(tagName).getId();
                        ObjectTag ot = new ObjectTag(credentialNo,villageCode,tagId);
                        tagList.add(ot);
                        hasTag = true;
                    }
                }
            }
            if(hasTag == false){
                String errorMsg = appendErrorMsg(fieldList.get(6).getTitle(), tagInput, fieldList.get(6).getErrorMsg());
                errorMessages.append(errorMsg);
                isError = true;
            }

            realPower.setRealPowerFlag(1);

            //判断当前行是否有错误
            if(isError){
                errorCount++;
                RealPowerExportModel exportModel = new RealPowerExportModel();
                exportModel.setCredentialType(credentialType);
                exportModel.setCredentialNo(credentialNo);
                exportModel.setCertificatesName(certificatesName);
                exportModel.setResidentialAddress(residentialAddress);
                exportModel.setPhoneNumber(phoneNumber);
                exportModel.setCompanyName(companyName);
                exportModel.setTagInput(tagInput);
                exportModel.setErrorMsg(errorMessages.toString());
                dataListCopy.add(exportModel);
            }else{
                powerList.add(realPower);
            }
        }

        try {
            progressTag.put(taskId, 20);
            if(!powerList.isEmpty()) {
                // 实有力量
                log.info("开始导入实有力量");
                dao.insertRealPower(powerList);
            }
            progressTag.put(taskId, 70);
            if(!tagList.isEmpty()){
                // 人员标签
                log.info("开始导入力量标签");
                tagDao.addObjectTag(tagList);
            }

            //正常的数据需要导入进去，错误的数据返回到Excel
            if (errorCount>0) {
                String errorFileName = exportExcelToLocal(taskId,fileName,headerTitle,dataListCopy);
                progressTag.put(taskId,100);
                return errorFileName;
            }
        } catch (Exception e) {
            log.error("导入实有力量错误,保存数据库异常！",e);
            throw new BusinessException(ExceptionCode.REALPOWER_NOTNULL_EXCEPTION_CODE,"导入实有力量错误,保存数据库异常！");
        }
        log.info("实有力量导入完成");
        progressTag.put(taskId, 100);
        return "";
    }

    @Override
    public int getImportDataProgress(String taskId) {
        return progressTag.get(taskId) == null ? 0 : progressTag.get(taskId);
    }

    @Override
    public void importPic (List<Map<String, Object>> pathList,String taskId) {
        try {
             progressPicTag.put(taskId,50);
             dao.updateBatchRealPower(pathList);
        } catch (Exception e) {
            log.error("导入实有力量照片失败！", e);
            progressPicTag.put(taskId,100);
            throw new BusinessException(ExceptionCode.REALPOWER_NOTNULL_EXCEPTION_CODE,"导入实有力量照片失败！");
        }
    }

    @Override
    public int getImportPicProgress(String taskId) {
        return progressTag.get(taskId) == null ? 0 : progressTag.get(taskId);
    }

}
